package aaa;
/*
  🦜 : Here are some static methods
 */

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.FileSystems;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.lang.RuntimeException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import aaa.Dt;

public class Utils {

    /*
      🦜 : substitute the content in the file between

      ....
      %%% --------------------------------------------------
      <content to be substituted>
      %%% --------------------------------------------------
    */
    static Boolean isSubstituteLine(String line){
        line = line.trim();
        return line.startsWith("%%%");
    }

    public static <T extends Dt.ITeXWorkable>
        void substituteSpecialLines(List<T> l, T dummy) throws IOException, RuntimeException{
        List<String> subs = new ArrayList<String>();
        for (T i : l) {
            subs.add(i.toTeXLine());
        }

        if (subs.isEmpty()){
            subs.add(dummy.getTeXEmpty());
        }

        substituteSpecialLines(dummy.getTeXTemplate(), subs);
    }

    static void substituteSpecialLines(String n, List<String> subs) throws IOException,
                                                                            RuntimeException
    {
        Path templateFile = FileSystems.getDefault().getPath("tex", n);
        Path outFile = FileSystems.getDefault().getPath(".generated-tex", n);
        substituteSpecialLines(templateFile, outFile, subs);
    }

    static void substituteSpecialLines(Path templateFile,
                                               Path outFile,
                                               List<String> subs) throws IOException,
                                                                            RuntimeException
    {
        // 1. read all lines
        List<String> readLines = Files.readAllLines(templateFile);

        // 2. get the `before` and `after`
        List<Integer> i = new ArrayList<Integer>(); // indexes of substitute lines
        for (int k = 0; k < readLines.size(); k++){
            String line = readLines.get(k);
            if (isSubstituteLine(line)){
                i.add(k);
            }
        }
        if (i.size() < 2){
            throw new RuntimeException("there should be at least two substitute lines in the template file");
        }
        // 🦜 : spit the lines into two parts (one before the first index line and one after the last index line)
        List<String> l1,l2;
        l1 = readLines.subList(0, i.get(0)+1); // +1 to include the last line (the substitute line)
        l2 = readLines.subList(i.get(i.size()-1), readLines.size()); // -1 to include the first line (the substitute line)

        // 3. concat and write
        List<String> lines = new ArrayList<String>();
        lines.addAll(l1);
        lines.addAll(subs);
        lines.addAll(l2);


        Files.write(outFile, lines);
    }

    // 生成随机 SHA-256 哈希值的方法
    public static String generateRandomSha256Hash() throws NoSuchAlgorithmException {

        byte[] randomBytes = generateRandomBytes();

        // 创建 MessageDigest 实例，选择 SHA-256 算法
        MessageDigest digest = MessageDigest.getInstance("SHA-256");

        // 更新摘要
        digest.update(randomBytes);

        // 获取摘要的字节数组
        byte[] hashedBytes = digest.digest();

        // 将字节数组转换为十六进制字符串
        StringBuilder stringBuilder = new StringBuilder();
        for (byte hashedByte : hashedBytes) {
            stringBuilder.append(Integer.toString((hashedByte & 0xff) + 0x100, 16).substring(1));
        }

        // 返回生成的 SHA-256 哈希值
        return stringBuilder.toString();
    }

    // 生成指定长度的随机字节数组
    private static byte[] generateRandomBytes() {
        SecureRandom secureRandom = new SecureRandom();
        byte[] randomBytes = new byte[16]; // 16 bytes for SHA-256
        secureRandom.nextBytes(randomBytes);
        return randomBytes;
    }

}
